import org.gradle.api.Plugin
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.initialization.Settings
import org.gradle.api.internal.GradleInternal
import org.gradle.api.internal.file.DefaultFileOperations
import org.gradle.api.internal.file.FileCollectionFactory
import org.gradle.api.internal.file.FileLookup
import org.gradle.api.logging.Logging
import org.gradle.util.GradleVersion
import java.io.File

class AndroidVersionCatalogPlugin : Plugin<Settings> {
    private val logger = Logging.getLogger("version-catalog")

    private fun getConfigurableFile(settings: Settings, path: String): ConfigurableFileCollection {
        val services = (settings.gradle as GradleInternal).services
        val fileResolver = services.get(FileLookup::class.java).getFileResolver(settings.rootDir)
        val fileCollectionFactory = services.get(FileCollectionFactory::class.java).withResolver(fileResolver)
        val fileOperations = DefaultFileOperations.createSimple(fileResolver, fileCollectionFactory, services)
        return fileOperations.configurableFiles(path)
    }

    private fun checkGradleVersion() {
        if (GradleVersion.current() < GradleVersion.version("7.2")) {
            errorOccur("Gradle version must be greater than 7.2, otherwise VersionCatalog feature cannot be used.")
        }
    }

    private fun errorOccur(message: String): Nothing {
        logger.error(message)
        error(message)
    }

    override fun apply(settings: Settings) {
        checkGradleVersion()

        settings.enableFeaturePreview("VERSION_CATALOGS")
        settings.gradle.settingsEvaluated {
            @Suppress("UnstableApiUsage")
            settings.dependencyResolutionManagement.versionCatalogs.apply {
                create("libs") {
                    from(getConfigurableFile(settings, "${settings.rootProject}/build-logic/gradle/libs.versions.toml"))
                }
            }
        }

        /*
        val extension =
            settings.extensions.create<RepositoriesPluginExtension>("repositoriesPlugin", RepositoriesPluginExtension::class.java)

        val localRepositoryName = extension.localRepositoryName?.let { it }?: "../../localRepo"
        val localRepositoryPath = extension.localRepositoryPath?.let { it }?: "../../local-repo"

        // read the properties
        val properties = settings.extensions.extraProperties
        val url = properties[PROP_REMOTE_URL]?.toString()
        val name = properties[PROP_REMOTE_CATALOG_NAME]?.toString()
        val expireMillis = properties.opt(PROP_EXPIRE_MILLIS)?.toString()?.toLong() ?: DEFAULT_CACHE_EXPIRE_MILLIS

        val dotGradleDir = Path("${settings.rootDir}/.gradle").toFile()
        val fileName = "${name}${FILE_NAME_SUFFIX}"
        val storagePath = properties.opt(PROP_REMOTE_CATALOG_PATH)?.toString()
        val storagePathFile = storagePath?.let { Path("${settings.rootDir}/$it").toFile() }
        val remoteFile = if (storagePathFile != null) {
            if (storagePathFile.isDirectory) {
                File(storagePathFile, "${name}${FILE_NAME_SUFFIX}")
            } else {
                errorOccur("Path is not exist, please check property: $PROP_REMOTE_CATALOG_PATH=${storagePathFile.path}")
            }
        } else {
            File(dotGradleDir, "${name}${FILE_NAME_SUFFIX}")
        }
        val lastUpdateAtFile = File(dotGradleDir, "$fileName$LAST_UPDATE_AT_SUFFIX")

        if (url.isNullOrBlank()) {
            errorOccur("Please define the property (${PROP_REMOTE_URL})")
        }

        if (name.isNullOrBlank()) {
            errorOccur("Please define the property（${PROP_REMOTE_CATALOG_NAME}）")
        }

        // If cache file is expired or not exist, download the file.
        val isExpired = System.currentTimeMillis() - getLastUpdateAt(lastUpdateAtFile) > expireMillis
        val isFileExist = remoteFile.exists() && remoteFile.length() > 0
        if (isExpired || isFileExist.not()) {
            logger.info("Download VersionCatalog file... $url")
            downloadRemoteVersionCatalogFile(url, remoteFile)
            writeLastUpdateAt(lastUpdateAtFile, System.currentTimeMillis())
            logger.info("Download successfully.")
        } else {
            logger.info("Version catalog file cache is valid, skip download (url: $url)")
        }

        settings.enableFeaturePreview("VERSION_CATALOGS")
        settings.gradle.settingsEvaluated {
            @Suppress("UnstableApiUsage")
            settings.dependencyResolutionManagement.versionCatalogs.apply {
                create("libs") {
                    from(getConfigurableFile(settings, File(storagePathFile, "${name}${FILE_NAME_SUFFIX}")))
                }
            }
        }

        settings.gradle.afterProject { project ->
            // Register the task for force download configuration file. (Skip the expiry time config)
            project.tasks.register("refreshRemoteVersionCatalog") { task ->
                task.group = "version-catalog"
                task.doLast {
                    downloadRemoteVersionCatalogFile(url, remoteFile)
                    writeLastUpdateAt(lastUpdateAtFile, System.currentTimeMillis())
                }
            }

            project.tasks.register("cleanRemoteVersionCatalog") { task ->
                task.group = "version-catalog"
                task.doLast {
                    remoteFile.delete()
                    lastUpdateAtFile.delete()
                    logger.info("The local VersionCatalog cache deleted. (${remoteFile.path})")
                }
            }
        }*/
    }


}
